package main;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import test.ItsTester;

/**
 * @author kinder112
 *
 */
public class BranchAndBound {

	private static ArrayList<Its> itsLists;
	private static int count;
	private static ResultSet results;
	private static Map<String, Double> goals;
	private static Map<String, Double> performance;
	private static int count2;
	private static int count3;

	/**
	 * @param objects 
	 * @param args
	 */

	static public ResultSet genereteResults(ArrayList<Its> pickedIts, Map<String, Double> goals, ResultSet results) {
		BranchAndBound.goals = goals;
		BranchAndBound.itsLists = pickedIts;
		BranchAndBound.results = results;
		count =  count2 = count3 = 0;
		List<Integer> start = new ArrayList<Integer>();
		List<Integer> end = new ArrayList<Integer>();
		for (int i = 0; i < itsLists.size(); i++)
			end.add(i);

		subgenerator(start, end);
		System.out.println("Went into " + count + " branches of total " + (int)Math.pow(2, itsLists.size()));
		System.out.println("Count2 " + count2);
//		for (Its i : itsLists) {
//			System.out.println("Its " + i);
//		}
		return results;
	}

	static private void subgenerator(List<Integer> start, List<Integer> end) {
		performance = null;
		count3++;
		if (meetsGoals(start)) {
			Map<String, Double> perCopy = new HashMap<String, Double>(performance);
			List<Integer> set = new ArrayList<Integer>(start);
			results.addItsSet(set, perCopy);
//			System.out.println("Meets Goals: " + start);
			count++;
			return;
		}
		if (end.size() == 0) {
		} else {
			start.add(end.get(0));
			end = end.subList(1, end.size());
			subgenerator(start, end);
			start.remove(start.size() - 1);
			subgenerator(start, end);
		}
	}

	private static Map<String, Double> calculatePerformance(List<Integer> start) {
		Map<String, Double> performance = new HashMap<String, Double>();
		for (String goal : goals.keySet()) {
			double partialPerformance = 0;
			for (Integer i : start) {
				partialPerformance += itsLists.get(i).getProblemPerf(goal); 
			}
//			System.out.println("For: " + start + "\n\tPutting: " + goal + " " + partialPerformance);
			performance.put(goal, new Double(partialPerformance));
		}
		return performance;
	}

	private static boolean meetsGoals(List<Integer> start) {
		count2++;
		performance = calculatePerformance(start);
		for (String goal : goals.keySet()) {
			if(goals.get(goal)> performance.get(goal))
				return false;
		}
		return true;
	}

	public void calculateResults() {

	}

	public static void main(String[] args) {
		Map<String, Double> goals = new HashMap<String, Double>();
		goals.put("emission", 0.7);
		ItsTester tester = new ItsTester();
		Its itsList[] = tester.generateIts();
		ArrayList<Its> tmp2  = new ArrayList<Its>();
		int tmp[] = new int[itsList.length];
		for(int i=0; i<itsList.length; i++){
			tmp[i] = i;
			tmp2.add(itsList[i]);
		}
		BranchAndBound.genereteResults(tmp2, goals, new ResultSet(tmp));
	}

}
